// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "SQLCreateFunctionStatement.h"
#include "../SQLParameter.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/listTran.h"
#include "../../../utils/instanceof.h"
#include "../expr/SQLPropertyExpr.h"

SQLCreateFunctionStatement::SQLCreateFunctionStatement()
{
  parameters = std::make_shared<std::list<SQLParameter_ptr>>();
}

SQLObject_ptr SQLCreateFunctionStatement::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SQLCreateFunctionStatement>(new SQLCreateFunctionStatement());
  std::shared_ptr<SQLCreateFunctionStatement> x = std::dynamic_pointer_cast<SQLCreateFunctionStatement>(clone_tmp);
  // SQLCreateFunctionStatement x = new SQLCreateFunctionStatement();

  if (definer != nullptr)
  {
    x->setDefiner(std::dynamic_pointer_cast<SQLName>(definer->clone()));
  }
  x->create = create;
  x->orReplace = orReplace;
  if (name != nullptr)
  {
    x->setName(std::dynamic_pointer_cast<SQLName>(name->clone()));
  }
  if (block != nullptr)
  {
    x->setBlock(std::dynamic_pointer_cast<SQLStatement>(block->clone()));
  }
  for (SQLParameter_ptr p : *parameters)
  {
    SQLParameter_ptr p2 = std::dynamic_pointer_cast<SQLParameter>(p->clone());
    p2->setParent(x);
    x->parameters->push_back(p2);
  }
  x->javaCallSpec = javaCallSpec;
  if (authid != nullptr)
  {
    x->setAuthid(std::dynamic_pointer_cast<SQLName>(authid->clone()));
  }
  if (returnDataType != nullptr)
  {
    x->setReturnDataType(std::dynamic_pointer_cast<SQLDataType>(returnDataType->clone()));
  }
  x->comment = comment;
  x->deterministic = deterministic;
  x->pipelined = pipelined;
  x->language = language;

  return x;
}

// @Override
void SQLCreateFunctionStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLCreateFunctionStatement)))
  {
    acceptChild(visitor, definer);
    acceptChild(visitor, name);
    SQLObject_list_ptr tmp = ListTran::tran_class<SQLParameter, SQLObject>(parameters);
    acceptChild(visitor, tmp);
    acceptChild(visitor, returnDataType);
    acceptChild(visitor, block);
  }
  visitor->endVisit(SharedObject(SQLCreateFunctionStatement));
}

SQLParameter_list_ptr SQLCreateFunctionStatement::getParameters()
{
  return parameters;
}

void SQLCreateFunctionStatement::setParameters(SQLParameter_list_ptr parameters)
{
  this->parameters = parameters;
}

SQLName_ptr SQLCreateFunctionStatement::getName()
{
  return name;
}

void SQLCreateFunctionStatement::setName(SQLName_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLCreateFunctionStatement));
  }
  this->name = x;
}

SQLStatement_ptr SQLCreateFunctionStatement::getBlock()
{
  return block;
}

void SQLCreateFunctionStatement::setBlock(SQLStatement_ptr block)
{
  if (block != nullptr)
  {
    block->setParent(SharedObject(SQLCreateFunctionStatement));
  }
  this->block = block;
}

SQLName_ptr SQLCreateFunctionStatement::getAuthid()
{
  return authid;
}

void SQLCreateFunctionStatement::setAuthid(SQLName_ptr authid)
{
  if (authid != nullptr)
  {
    authid->setParent(SharedObject(SQLCreateFunctionStatement));
  }
  this->authid = authid;
}

string_ptr SQLCreateFunctionStatement::getLanguage()
{
  return language;
}

void SQLCreateFunctionStatement::setLanguage(string_ptr language)
{
  this->language = language;
}

BOOL_ptr SQLCreateFunctionStatement::isOrReplace()
{
  return orReplace;
}

void SQLCreateFunctionStatement::setOrReplace(BOOL_ptr orReplace)
{
  this->orReplace = orReplace;
}

SQLName_ptr SQLCreateFunctionStatement::getDefiner()
{
  return definer;
}

void SQLCreateFunctionStatement::setDefiner(SQLName_ptr definer)
{
  this->definer = definer;
}

BOOL_ptr SQLCreateFunctionStatement::isCreate()
{
  return create;
}

void SQLCreateFunctionStatement::setCreate(BOOL_ptr create)
{
  this->create = create;
}

string_ptr SQLCreateFunctionStatement::getJavaCallSpec()
{
  return javaCallSpec;
}

void SQLCreateFunctionStatement::setJavaCallSpec(string_ptr javaCallSpec)
{
  this->javaCallSpec = javaCallSpec;
}

SQLDataType_ptr SQLCreateFunctionStatement::getReturnDataType()
{
  return returnDataType;
}

void SQLCreateFunctionStatement::setReturnDataType(SQLDataType_ptr returnDataType)
{
  if (returnDataType != nullptr)
  {
    returnDataType->setParent(SharedObject(SQLCreateFunctionStatement));
  }
  this->returnDataType = returnDataType;
}

string_ptr SQLCreateFunctionStatement::getComment()
{
  return comment;
}

void SQLCreateFunctionStatement::setComment(string_ptr comment)
{
  this->comment = comment;
}

BOOL_ptr SQLCreateFunctionStatement::isDeterministic()
{
  return deterministic;
}

void SQLCreateFunctionStatement::setDeterministic(BOOL_ptr deterministic)
{
  this->deterministic = deterministic;
}

string_ptr SQLCreateFunctionStatement::getSchema()
{
  SQLName_ptr name = getName();
  if (name == nullptr)
  {
    return nullptr;
  }

  if (instanceof <SQLName, SQLPropertyExpr>(name))
  {
    return (std::dynamic_pointer_cast<SQLPropertyExpr>(name))->getOwnernName();
  }

  return nullptr;
}

// @Override
SQLDataType_ptr SQLCreateFunctionStatement::getDataType()
{
  return returnDataType;
}

// @Override
void SQLCreateFunctionStatement::setDataType(SQLDataType_ptr dataType)
{
  this->setReturnDataType(dataType);
}

BOOL_ptr SQLCreateFunctionStatement::isParallelEnable()
{
  return parallelEnable;
}

void SQLCreateFunctionStatement::setParallelEnable(BOOL_ptr parallel_enable)
{
  this->parallelEnable = parallel_enable;
}

BOOL_ptr SQLCreateFunctionStatement::isAggregate()
{
  return aggregate;
}

void SQLCreateFunctionStatement::setAggregate(BOOL_ptr aggregate)
{
  this->aggregate = aggregate;
}

SQLName_ptr SQLCreateFunctionStatement::getUsing()
{
  return using_;
}

void SQLCreateFunctionStatement::setUsing(SQLName_ptr using_)
{
  this->using_ = using_;
}

BOOL_ptr SQLCreateFunctionStatement::isPipelined()
{
  return pipelined;
}

void SQLCreateFunctionStatement::setPipelined(BOOL_ptr pipelined)
{
  this->pipelined = pipelined;
}

BOOL_ptr SQLCreateFunctionStatement::isResultCache()
{
  return resultCache;
}

void SQLCreateFunctionStatement::setResultCache(BOOL_ptr resultCache)
{
  this->resultCache = resultCache;
}

string_ptr SQLCreateFunctionStatement::getWrappedSource()
{
  return wrappedSource;
}

void SQLCreateFunctionStatement::setWrappedSource(string_ptr wrappedSource)
{
  this->wrappedSource = wrappedSource;
}

BOOL_ptr SQLCreateFunctionStatement::isTemporary()
{
  return temporary;
}

void SQLCreateFunctionStatement::setTemporary(BOOL_ptr temporary)
{
  this->temporary = temporary;
}

BOOL_ptr SQLCreateFunctionStatement::isIfNotExists()
{
  return ifNotExists;
}

void SQLCreateFunctionStatement::setIfNotExists(BOOL_ptr ifNotExists)
{
  this->ifNotExists = ifNotExists;
}
